﻿using System;
using System.ComponentModel;
using System.Globalization;
using System.Threading;

namespace FYControls.Controls
{
    public class DateTimeConverter: TypeConverter
    {
        public const string DEFAULT_CULTUREID = "en-US";
        public const string DEFAULT_CALENDAR = "gregorian";

        public static CultureInfo CultureInfo = new CultureInfo(DEFAULT_CULTUREID);
        public static Calendar Calendar = TimelineCalendar.CalendarFromString(DEFAULT_CALENDAR);

        private static string m_cultId = DEFAULT_CULTUREID;
        private static string m_calendarType = DEFAULT_CALENDAR;

        public static string CultureId
        {
            get
            {
                return m_cultId;
            }
            set
            {
                CultureInfo = new CultureInfo(value);
                CultureInfo.DateTimeFormat.Calendar = Calendar;

                m_cultId = value;
            }
        }

        public static string CalendarName
        {
            get
            {
                return m_calendarType;
            }
            set
            {
                m_calendarType = String.IsNullOrEmpty(value) ? DEFAULT_CALENDAR : value;
                Calendar = TimelineCalendar.CalendarFromString(m_calendarType);

                CultureInfo.DateTimeFormat.Calendar = Calendar;
            }
        }

        public override bool CanConvertFrom(
            ITypeDescriptorContext context, 
            Type sourceType
        )
        {
            if (sourceType == typeof(string))
            {
                return true;
            }
            return base.CanConvertFrom(context, sourceType);
        }

        public override bool CanConvertTo(
            ITypeDescriptorContext context, 
            Type destinationType
        )
        {   
            if (destinationType == typeof(string))
            {
                return true;
            }

            return base.CanConvertTo(context, destinationType);
        }

        public override object ConvertTo(
            ITypeDescriptorContext context, 
            CultureInfo culture, 
            object value, 
            Type destinationType
        )
        {
            if (destinationType == typeof(string))
            {
                return value.ToString();
            }

            return base.ConvertTo(context, culture, value, destinationType);
        }

        public override object ConvertFrom(
            ITypeDescriptorContext context, 
            CultureInfo culture, 
            object value
        )
        {
            if (value.GetType() == typeof(string))
            {
                return ParseDateTime((string) value);
            }
            return base.ConvertFrom(context, culture, value);
        }

        /// 
        /// <summary>
        /// Parse initial date passed from XAML, could be DateTime string or 'today', 
        /// 'now', 'yesterday', etc. constants.</summary>
        /// 
        public static DateTime ParseDateTime(string initialTime)
        {
            DateTime initTime;
            switch(initialTime.ToLower())
            {
                case "tomorrow":
                    initTime = DateTime.Today.AddDays(1);
                    break;

                case "today":
                    initTime = DateTime.Today;
                    break;

                case "yesterday":
                    initTime = DateTime.Today.AddDays(-1);
                    break;

                case "now":
                    initTime = DateTime.Now;
                    break;

                default:
                    initTime = DateTime.Parse(initialTime, DateTimeConverter.CultureInfo);
                    break;
            }

            return initTime;
        }

        public static string GetDecades(DateTime dt)
        {
            return ((Calendar.GetYear(dt) / 10) * 10).ToString();
        }

        public static string GetYear(DateTime dt)
        {
            return dt.ToString("yyyy", CultureInfo);
        }

        public static string GetMonth(DateTime dt)
        {
            string ret;
            if (Calendar.GetMonth(dt) == 1)
            {
                ret = dt.ToString("MMM yyyy", CultureInfo);
            }
            else
            {
                ret = dt.ToString("MMM");
            }

            return ret;
        }

        public static string GetDay(DateTime dt)
        {
            string ret;

            if (Calendar.GetDayOfMonth(dt) == 1)
            {
                ret = Calendar.GetDayOfMonth(dt).ToString() + " " + GetMonth(dt);
            }
            else
            {
                ret = Calendar.GetDayOfMonth(dt).ToString();
            }

            return ret;
        }
    }
}
